An Extended Debugging Session

This section illustrates use of the Scheme ndexfile(index-entry "debug" "tt" aux )debug procedure in an extended session. The first example is the buggy fact procedure that was used as an example in section [*] above. The sequence begins with the interaction already described in section [*].

$\Longrightarrow$
$\Longrightarrow$ unspecified error `=̀13`


          

[1 REP] (define (fact n) (if (zero? n) l (* n (fact (-1+ n))))) FACT

[1 REP] (fact 3) Unbound Variable L Error!

[2 Error] (debug) Subproblem Level: 0 Reduction Number: 0 Expression: L within the procedure FACT. applied to (0)

[3 Debug] s Subproblem Level: 0 Reduction Number: 0 Expression: L within Procedure FACT applied to (0)

The command S displays the current subproblem. The command B moves backwards in time. $\Longrightarrow$
$\Longrightarrow$ unspecified error `=̀13`

          [3 Debug] b     Subproblem Level: 0  Reduction Number: 1     Expression:     (IF (ZERO? N) L (* N (FACT (-1+ N))))      within Procedure FACT     applied to (0)

[3 Debug] b Subproblem Level: 0 Reduction Number: 2 Expression: (FACT (-1+ N)) within Procedure FACT applied to (1)

[3 Debug] b Subproblem Level: 1 Reduction Number: 0 Expression: (* N (FACT (-1+ N))) within Procedure FACT applied to (1)

The F command moves forward through reductions one at a time, in the opposite direction to B. $\Longrightarrow$
$\Longrightarrow$ unspecified error `=̀13`

          [3 Debug] f     Subproblem Level: 0  Reduction Number: 2     Expression:     (FACT (-1+ N))      within Procedure FACT     applied to (1)

[3 Debug] f Subproblem Level: 0 Reduction Number: 1 Expression: (IF (ZERO? N) L (* N (FACT (-1+ N)))) within Procedure FACT applied to (0)

[3 Debug] f Subproblem Level: 0 Reduction Number: 0 Expression: L within Procedure FACT applied to (0)

We are now back at the subproblem level containing the offending expression. The variable L is unbound. The Z (for ZAP) command asks for an expression to evaluate and returns this value as the value of the current subproblem to the previous subproblem, that is, the containing subproblem. Here we wanted L to be 1. $\Longrightarrow$
$\Longrightarrow$ unspecified error `=̀13`

          [3 Debug] z     Enter an expression to EVALUATE and CONTINUE with: 1      That evaluates to:

1 Confirm: [Y or N] -> y 6

And here is the correct result. Let's look at another example: $\Longrightarrow$
$\Longrightarrow$ unspecified error `=̀13`

          

[1 REP] (define (square-root x) (define (square-root-iter ans) (if (close? ans) ans (square-root-iter (average (/ x ans) ans)))) (define (close? ans)(< (abs (- (* ans asn) x)) .0001)) (square-root-iter 1))

SQUARE-ROOT

[1 REP] (square-root 4) Unbound Variable ASN Error! Level: 2

[2 Error] (debug) Subproblem Level: 0 Reduction Number: 0 Expression: ASN within Procedure CLOSE? applied to (1)

[3 Debug] b Subproblem Level: 1 Reduction Number: 0 Expression: (* ANS ASN) within Procedure CLOSE? applied to (1)

[3 Debug] b Subproblem Level: 2 Reduction Number: 0 Expression: (- (* ANS ASN) X) within Procedure CLOSE? applied to (1)

[3 Debug] b Subproblem Level: 3 Reduction Number: 0 Expression: (ABS (- (* ANS ASN) X)) within Procedure CLOSE? applied to (1)

[3 Debug] b Subproblem Level: 4 Reduction Number: 0 Expression: (< (ABS (- (* ANS ASN) X)) .0001) within Procedure CLOSE? applied to (1)

Above is a square root program that is divided into sub-procedures. In the program there is a bug. The debugger was called to reveal that the unbound variable ASN is in the expression (* ans asn) in the procedure CLOSE?.

Here is another example:

$\Longrightarrow$
$\Longrightarrow$ unspecified error `=̀13`


          [1 REP] (define (sum term low high)           (define (sum-iter sum index)              (if (> index high)                 sum                 (sum-iter (+ sum (term index)) (1+ index))))           (sum-iter 0 low)) SUM 

[1 REP] (define (term-proc i)(if (evin? i) 1 0)) TERM-PROC

[1 REP] (pp term-proc) (DEFINE (TERM-PROC I) (IF (EVIN? I) 1 0))

[1 REP] (sum term-proc 1 5) Unbound Variable EVIN? Error!

[2 Error] (debug) Subproblem Level: 0 Reduction Number: 0 Expression: EVIN? within Procedure TERM-PROC applied to (1)

[3 Debug] b Subproblem Level: 1 Reduction Number: 0 Expression: (EVIN? I) within Procedure TERM-PROC applied to (1)

[3 Debug] b Subproblem Level: 2 Reduction Number: 0 Expression: (IF (EVIN? I) 1 0) within Procedure TERM-PROC applied to (1)

[3 Debug] b Subproblem Level: 3 Reduction Number: 0 Expression: (+ SUM (TERM INDEX)) within Procedure SUM-ITER applied to (0 1)

[3 Debug] h Sub Prb. Procedure Name Expression

0 TERM-PROC EVIN? 1 TERM-PROC (EVIN? I) 2 TERM-PROC (IF (EVIN? I) 1 0) 3 SUM-ITER (+ SUM (TERM INDEX)) 4 SUM-ITER (SUM-ITER (+ SUM (TERM INDEX)) (1+ INDEX))

The bug here is that the procedure EVEN? was spelled EVIN?, in the definition of the procedure TERM-PROC. By looking at the history we can see that the procedure SUM was called somewhere at subproblem 4. The command G used below goes to a specified subproblem and reduction. Below we see the call to SUM in subproblem 4, reduction 4.

$\Longrightarrow$
$\Longrightarrow$ unspecified error `=̀13`


          [3 Debug] g Subproblem number: 4  Reduction Number (0 through 4 inclusive): 4 

Subproblem Level: 4 Reduction Number: 4 Expression: (SUM TERM-PROC 1 5) within a MAKE-PACKAGE special form applied to (#<ENVIRONMENT 13033164>)

[3 Debug] c Frame created by a MAKE-PACKAGE special form. Has bindings:

USER-INITIAL-ENVIRONMENT = #<ENVIRONMENT 13833016> SUM = #<COMPOUND-PROCEDURE SUM> TERM-PROC = #<COMPOUND-PROCEDURE TERM-PROC>

The environment in which subproblem 4 was being evaluated is the user-initial-environment. The C command displayes the variable bindings in the evaluation environment of the current subproblem. Which in this case is the user-initial-environment. This is where evin? should be defined. The V command evaluates an expression in the current environment.

$\Longrightarrow$
$\Longrightarrow$ unspecified error `=̀13`


          [3 Debug] v [3 Eval] (define evin? even?) EVIN? 

[3 Debug] c Frame created by a MAKE-PACKAGE special form Has bindings:

USER-INITIAL-ENVIRONMENT = #<ENVIRONMENT 13833016> SUM = #<COMPOUND-PROCEDURE SUM> TERM-PROC = #<COMPOUND-PROCEDURE TERM-PROC> EVIN? = #'<COMPOUND-PROCEDURE EVEN?>

[3 Debug] q

[2 Error] (proceed) 2

Above we defined the variable evin? to have as its value the procedure even?. We then left the debugger. By typing (proceed) at the error prompt we cause the program to continue with the evaluation of the expression that caused the error, and the procedure completes returning the correct answer.